use std::time::Duration;
use tokio::{io::{AsyncWriteExt, WriteHalf}, net::TcpStream, time::timeout};
use crate::{error::{new_err, AppErr}, service::{frame::{make, CMD_LOGIN}, model::LoginReq, reader::read_frame}, utils::get_mac_address, MAC_NAME};
use super::{conn::Reader, frame::{TYPE_REQ, TYPE_RES}, model::LoginRes};


pub async fn wait_login(w: &mut WriteHalf<TcpStream>, r: &mut Reader) -> Result<LoginRes, AppErr> {

    let req = LoginReq {
        mac_addr: get_mac_address(MAC_NAME)?,
    };
    let buf = make(TYPE_REQ, 0, CMD_LOGIN, &serde_cbor::to_vec(&req)?.into_boxed_slice());
    w.write_all(&buf).await?;

    let frame = timeout(Duration::from_secs(5), read_frame(r)).await
        .map_err(|_| new_err("login timeout"))??;

    if frame.ctype() != TYPE_RES {
        return Err(new_err("login fail not res"));
    }
    if frame.cmd()? != CMD_LOGIN {
        return Err(new_err("is not login"));
    }
    let res: LoginRes = frame.parse()?;
    
    Ok(res)
}









